import cv2
import numpy as np
from py_base.tools import win32


def adjust(img, c, b):
    h, w, r = img.shape
    blank = np.zeros([h, w, r], img.dtype)
    dst = cv2.addWeighted(img, c, blank, 1 - c, b)
    return dst


def closing(frame, n):
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (n, n))
    closing = cv2.morphologyEx(frame, cv2.MORPH_CLOSE, kernel)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (n, n))
    closing = cv2.morphologyEx(closing, cv2.MORPH_CLOSE, kernel)
    return closing


def opening(frame, n):
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (n, n))
    closing = cv2.morphologyEx(frame, cv2.MORPH_OPEN, kernel)
    return closing


def diffImg(img, is_test=False):
    h_img, w_img = img.shape[:2]  # (行数，列数，通道数) 这里获取前两个元素
    area = h_img * w_img

    imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 灰度化图片

    ret, thresh = cv2.threshold(imgray, 127, 255, 0)  # 阈值分割，亮度<127的亮度=0

    # 找轮廓，寻找两个图片框
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    # 将轮廓画在img上
    # cv2.drawContours(img, contours, -1, (0, 0, 0), 2)
    # cv2.imshow('轮廓查找1', img)
    # cv2.waitKey(0)

    # 遍历轮廓，找到最大的两个，认为是两个图片框
    rois = []
    for cnt in contours:
        x, y, w, h = cv2.boundingRect(cnt)
        if area // 7 < w * h < area // 6.5:
            rois.append([x + 10, y + 10, w - 10, h - 10])  # 两个图的边框区域颜色不一样，会影响后面的判断，这里缩小取值范围，去掉边框
    lets = len(rois)
    # if lets < 2:
    # raise Exception("找不到两个图框。" + str(lets))

    # 分析截图得到的图框精确值
    # img[行, 列] y,x
    roi1 = img[312:598, 93:474]
    roi2 = img[312:598, 550:931]

    # 求图框区到整个窗口截图边缘的距离
    # 左边的框的x点
    xdot = 93
    ydot = 312

    roi = cv2.absdiff(roi1, roi2)  # 两个图片每个像素点的绝对值输出为一个新图片，一样的像素点就会变黑

    frame = adjust(roi, 1.3, 0)  # 提升明度
    roigray_out = frame.copy()

    roigray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    if is_test:
        cv2.imshow('1', roigray)

    roigray = closing(roigray, 10)  # 降低内部噪点
    # roigray = opening(roigray, 5)  # 降低内部噪点
    if is_test:
        cv2.imshow('2', roigray)

    ret, thresh = cv2.threshold(roigray, 35, 255, 0)  # 再次阈值化
    if is_test:
        cv2.imshow('3', thresh)

    thresh = closing(thresh, 6)  # 降低内部噪点
    # thresh = closing(thresh, 10)  # 降低内部噪点
    thresh = opening(thresh, 3)  # 降低内部噪点

    if is_test:
        cv2.imshow('4', thresh)

    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    cv2.drawContours(roi1, contours, -1, (0, 0, 0), 2)

    dots = []
    # 框出不同之处
    for cnt in contours:
        x, y, w, h = cv2.boundingRect(cnt)
        cv2.rectangle(roi1, (x, y), (x + w, y + h), (0, 255, 0), 3)

        # 画到原截图上
        # 画一个填充红色的圆，参数 2：圆心坐标，参数 3：半径
        x = xdot + x + int(w / 2)
        y = ydot + y + int(h / 2)
        # cv2.circle(img, (x, y), 6, (0, 0, 255), -1)
        dots.append([x, y])

    dpi = win32.getDpi()
    res2 = cv2.resize(roi1, None, fx=dpi, fy=dpi, interpolation=cv2.INTER_LINEAR)

    if is_test:
        cv2.waitKey(0)

    return roigray_out, thresh, dots
